<template>
  <div class="search-list-box">
    <div class="search-group" :style="{ padding: paddingStyle }">
      <div class="group-left" :style="`height:${checkLeftHeight}px`">
        <div class="group-list-wrap">
          <div
            class="group-item-wrap"
            v-for="(item, index) in searchShowList"
            :key="index"
            :style="{ width: item.width + '%' }"
            :class="{ 'is-need': item.isNeed }"
          >
            <div class="search-label" :style="{ minWidth: widthLabel + 'px' }">
              <span class="star">*</span>
              <span>{{ item.label }}</span>
            </div>
            <div class="search-item-right">
              <template v-if="item.type == 'input'">
                <el-input
                  ref="input"
                  v-model="item.value"
                  clearable
                  @blur="inputBlurHandle(item)"
                  :placeholder="`请输入${item.label}`"
                  @keyup.enter.native="enterSearch"
                  @clear="clearValueHandle(item)"
                ></el-input>
              </template>
              <template v-if="item.type == 'select'">
                <el-select
                  v-model="item.value"
                  placeholder="请选择"
                  clearable
                  :filterable="item.filterable"
                  @change="selectChangeHandle(item)"
                >
                  <el-option
                    v-for="(item, index) in item.list"
                    :key="index"
                    :label="item.label"
                    :value="item.value"
                  >
                  </el-option>
                </el-select>
              </template>
              <template v-if="item.type == 'multiSelect'">
                <el-select
                  v-model="item.value"
                  multiple
                  collapse-tags
                  clearable
                  :filterable="item.filterable"
                  placeholder="请选择(可多选)"
                  @change="selectChangeHandle(item)"
                >
                  <el-option
                    v-for="(item, index) in item.list"
                    :key="index"
                    :label="item.label"
                    :value="item.value"
                  >
                  </el-option>
                </el-select>
              </template>
              <template v-if="item.type == 'location'">
                <el-cascader
                  :props="props"
                  :clearable="false"
                  @change="locationChangeHandle(item)"
                  v-model="item.value"
                  ref="cascaderAddr"
                  popper-class="cascader-color"
                  separator=" - "
                ></el-cascader>
              </template>
              <template v-if="item.type == 'daterange'">
                <el-date-picker
                  v-model="item.value"
                  :clearable="item.isNeed !== true"
                  type="daterange"
                  range-separator="-"
                  start-placeholder="开始日期"
                  end-placeholder="结束日期"
                  value-format="yyyy-MM-dd"
                  @change="dateChangeHandle(item)"
                >
                </el-date-picker>
                <el-radio-group
                  v-if="item.timePeriod"
                  v-model="item.radio"
                  style="margin-left: 16px"
                  v-removeAriaHidden
                  @input="dateRadioChange($event, 'searchShowList', item)"
                >
                  <el-radio v-if="item.isToday" :label="0">今日</el-radio>
                  <el-radio :label="1">最近一周</el-radio>
                  <el-radio :label="2">最近一月</el-radio>
                  <el-radio :label="3">最近三月</el-radio>
                </el-radio-group>
              </template>
              <template v-if="item.type == 'datetimerange'">
                <el-date-picker
                  v-model="item.value"
                  type="datetimerange"
                  range-separator="-"
                  start-placeholder="开始日期"
                  end-placeholder="结束日期"
                  :format="item.sFormat ? item.sFormat : 'yyyy-MM-dd HH:mm'"
                  :value-format="
                    item.vFormat ? item.vFormat : 'yyyy-MM-dd HH:mm'
                  "
                  @change="dateChangeHandle(item)"
                >
                </el-date-picker>
              </template>
              <template v-if="item.type == 'date'">
                <el-date-picker
                  v-model="item.value"
                  type="date"
                  placeholder="选择日期"
                  value-format="yyyy-MM-dd HH:mm:ss"
                  @change="selectChangeHandle(item)"
                >
                </el-date-picker>
              </template>
              <template v-if="item.type == 'checkbox'">
                <div class="check-box">
                  <div
                    class="check-item"
                    v-for="(citem, cindex) in item.list"
                    :key="citem.label"
                  >
                    <div
                      class="check-icon"
                      :class="{ active: citem.checked }"
                      @click="changeCheckHandles(citem, item, cindex)"
                    ></div>
                    <div class="check-label">{{ citem.label }}</div>
                  </div>
                </div>
              </template>
              <template v-if="item.type == 'cascader'">
                <el-cascader
                  :props="
                    item.props || {
                      label: 'label',
                      value: 'value',
                      children: 'children',
                    }
                  "
                  style="width: 100%"
                  v-model="item.value"
                  :options="item.list"
                  @change="
                    $emit(
                      item.changeMethod || 'cascaderChangeMethod',
                      $event,
                      item,
                      indx
                    )
                  "
                  separator=" - "
                >
                </el-cascader>
              </template>
              <template v-if="item.type == 'loadselect'">
                <TrLoadSelect
                  v-model="item.value"
                  :requestObj="item.requestObj"
                  :ftObject="item"
                  :defaultParams="item.defaultParams"
                  :disabled="
                    item.disabled !== undefined ? item.disabled : false
                  "
                  :outSelectLabel="item.selectedLabel"
                  :isSaveLoad="item.isSaveLoad"
                  :searchPlaceholder="item.searchPlaceholder"
                  @change="changeSelectHandle"
                  @clear="clearValueHandle"
                />
              </template>
              <!-- <template v-if="item.type == 'dept'">
                <avue-input-tree
                  class="border-red"
                  style="width: 100%"
                  :default-expand-all="false"
                  v-model="item.value"
                  placeholder="请选择"
                  :dic="deptDic"
                  :clearable="false"
                  @change="deptChangeSelectHandle(item)"
                ></avue-input-tree>
              </template> -->
            </div>
          </div>
        </div>
        <transition name="el-zoom-in-top">
          <div class="search-hidden-wrap" v-show="isExpanded">
            <div class="group-list-wrap">
              <div
                class="group-item-wrap"
                v-for="(item, index) in searchHideList"
                :key="index"
                :style="{ width: item.width + '%' }"
                :class="{ 'is-need': item.isNeed }"
              >
                <div
                  class="search-label"
                  :style="{ minWidth: widthLabel + 'px' }"
                >
                  <span class="star">*</span>
                  <span>
                    {{ item.label }}
                  </span>
                </div>
                <div class="search-item-right">
                  <template v-if="item.type == 'input'">
                    <el-input
                      v-model="item.value"
                      ref="input"
                      clearable
                      :placeholder="`请输入${item.label}`"
                      @blur="inputBlurHandle(item)"
                      @keyup.enter.native="searchHandle"
                      @clear="clearValueHandle(item)"
                    ></el-input>
                  </template>
                  <template v-if="item.type == 'select'">
                    <el-select
                      v-model="item.value"
                      placeholder="请选择"
                      clearable
                      :filterable="item.filterable"
                      @change="selectChangeHandle(item)"
                    >
                      <el-option
                        v-for="(item, index) in item.list"
                        :key="index"
                        :label="item.label"
                        :value="item.value"
                      >
                      </el-option>
                    </el-select>
                  </template>
                  <template v-if="item.type == 'multiSelect'">
                    <el-select
                      v-model="item.value"
                      multiple
                      collapse-tags
                      clearable
                      placeholder="请选择(可多选)"
                      @change="selectChangeHandle(item)"
                    >
                      <el-option
                        v-for="(item, index) in item.list"
                        :key="index"
                        :label="item.label"
                        :value="item.value"
                      >
                      </el-option>
                    </el-select>
                  </template>
                  <template v-if="item.type == 'daterange'">
                    <el-date-picker
                      v-model="item.value"
                      type="daterange"
                      range-separator="-"
                      start-placeholder="开始日期"
                      end-placeholder="结束日期"
                      value-format="yyyy-MM-dd"
                      @change="dateChangeHandle(item)"
                    >
                    </el-date-picker>
                    <el-radio-group
                      v-removeAriaHidden
                      v-if="item.timePeriod"
                      v-model="item.radio"
                      style="margin-left: 16px"
                      @input="dateRadioChange($event, 'searchHideList', item)"
                    >
                      <el-radio v-if="item.isToday" :label="0">今日</el-radio>
                      <el-radio :label="1">最近一周</el-radio>
                      <el-radio :label="2">最近一月</el-radio>
                      <el-radio :label="3">最近三月</el-radio>
                    </el-radio-group>
                  </template>
                  <template v-if="item.type == 'datetimerange'">
                    <el-date-picker
                      v-model="item.value"
                      type="datetimerange"
                      range-separator="-"
                      start-placeholder="开始日期"
                      end-placeholder="结束日期"
                      :format="item.sFormat ? item.sFormat : 'yyyy-MM-dd HH:mm'"
                      :value-format="
                        item.vFormat ? item.vFormat : 'yyyy-MM-dd HH:mm'
                      "
                      @change="dateChangeHandle(item)"
                    >
                    </el-date-picker>
                  </template>
                  <template v-if="item.type == 'date'">
                    <el-date-picker
                      v-model="item.value"
                      type="date"
                      placeholder="选择日期"
                      value-format="yyyy-MM-dd"
                      @change="selectChangeHandle(item)"
                    >
                    </el-date-picker>
                  </template>
                  <!-- <template v-if="item.type == 'dept'">
                    <avue-input-tree
                      class="border-red"
                      style="width: 100%"
                      :default-expand-all="false"
                      v-model="item.value"
                      placeholder="请选择"
                      :dic="deptDic"
                      :clearable="false"
                      @change="deptChangeSelectHandle(item)"
                    ></avue-input-tree>
                  </template> -->
                  <template v-if="item.type == 'checkbox'">
                    <div class="check-box">
                      <div
                        class="check-item"
                        v-for="(citem, cindex) in item.list"
                        :key="citem.label"
                      >
                        <div
                          class="check-icon"
                          :class="{ active: citem.checked }"
                          @click="changeCheckHandles(citem, item, cindex)"
                        ></div>
                        <div class="check-label">{{ citem.label }}</div>
                      </div>
                    </div>
                  </template>
                  <template v-if="item.type == 'location'">
                    <el-cascader
                      :props="props"
                      clearable
                      @change="locationChangeHandle(item)"
                      v-model="item.value"
                      ref="cascaderAddr"
                      popper-class="cascader-color"
                      separator=" - "
                    ></el-cascader>
                  </template>
                  <template v-if="item.type == 'loadselect'">
                    <TrLoadSelect
                      v-model="item.value"
                      :requestObj="item.requestObj"
                      :defaultParams="item.defaultParams"
                      :ftObject="item"
                      :disabled="
                        item.disabled !== undefined ? item.disabled : false
                      "
                      :outSelectLabel="item.selectedLabel"
                      :isSaveLoad="item.isSaveLoad"
                      :searchPlaceholder="item.searchPlaceholder"
                      @change="changeSelectHandle"
                      @clear="clearValueHandle"
                    />
                  </template>
                </div>
              </div>
            </div>
          </div>
        </transition>
      </div>
      <div class="group-right" :class="{ unneed: !searchHideList.length }">
        <div
          v-if="searchHideList.length > 0"
          class="open-btn"
          :class="{ active: isExpanded }"
          @click="openHandle"
        >
          {{ isExpanded ? "收起" : "展开" }}
        </div>
        <div class="search-btn search" @click="searchHandle">查询</div>
        <div class="search-btn reset" @click="resetParamsHandle">重置</div>
      </div>
    </div>
  </div>
</template>

<script>
import { findByProperty } from "@/utils/util";
import moment from "moment";
import { cloneDeep } from "lodash-es";
import TrLoadSelect from "@/components/Tr-load/Tr-load.vue";
export default {
  components: {
    TrLoadSelect,
  },
  props: {
    paddingStyle: {
      type: String,
      default: "24px",
    },
    labelWidth: {
      type: Number,
      default: 72,
    },
    searchShowList: {
      type: Array,
      default: () => [],
    },
    searchHideList: {
      type: Array,
      default: () => [],
    },
    value: {
      type: Object,
      default: () => {},
    },
    isDeepSearch: {
      type: Boolean,
      default: false,
    },
    currentWord: {
      type: String,
      default: "pageNo",
    },
  },
  computed: {
    checkHideRow() {
      let total = 0;
      this.searchHideList.forEach((item) => {
        total += item.width;
      });
      return Math.ceil(total / 100);
    },
    checkLeftHeight() {
      return this.isExpanded ? 56 * this.checkHideRow + 32 : 32;
    },
  },
  watch: {
    "searchShowList.length": {
      handler() {
        this.$nextTick(() => {
          this.getLabelWidth();
        });
      },
    },
    "searchHideList.length": {
      handler() {
        this.$nextTick(() => {
          this.getLabelWidth();
        });
      },
    },
  },
  data: () => ({
    isExpanded: false,
    cloneParams: {},
    initParams: {},
    cloneSearchShowList: [],
    cloneSearchHideList: [],
    widthLabel: 72,
  }),
  methods: {
    initParamsHandle() {
      this.searchShowList.forEach((item) => {
        if (item.type == "daterange" && item.timePeriod) {
          if (item.radio < 0) return;
          this.dateRadioChange(item.radio, "searchShowList", item);
        }
      });
      this.searchHideList.forEach((item) => {
        if (item.type == "daterange" && item.timePeriod) {
          if (item.radio < 0) return;
          this.dateRadioChange(item.radio, "searchHideList", item);
        }
      });
    },
    changeSelectHandle(val) {
      this.cloneParams[val.ftId] = val.rlValue;
    },
    dateRadioChange(label, list, val) {
      // 单选改变;
      const dayMap = {
        0: 0,
        1: 7,
        2: 30,
        3: 90,
      };
      const days = dayMap[label];
      const before = moment()
        .subtract(days, "days")
        .startOf("day")
        .format("YYYY-MM-DD HH:mm:ss");
      let now = moment().endOf("day").format("YYYY-MM-DD HH:mm:ss");
      this[list].map((item) => {
        if (item.type === "daterange" && item.id == val.id) {
          item.value = [before, now];
          this.cloneParams[val.startStr] = before;
          this.cloneParams[val.endStr] = now;
        }
      });
    },
    resetListHandle(arr, list) {
      arr.forEach((item) => {
        if (Array.isArray(item.value)) {
          item.value = [];
        } else {
          if (item.defaultValue) {
            item.value = item.defaultValue;
            return;
          }
          item.value = "";
        }
        if (item.type == "checkbox") {
          item.list.forEach((v) => {
            v.checked = v.id == 1;
          });
        }
        if (item.type == "daterange") {
          const column = findByProperty(this[list], "id", item.id);
          item.radio = column.radio;
          item.value = column.value;
        }
      });
    },
    resetParamsHandle() {
      this.resetListHandle(this.searchShowList, "cloneSearchShowList");
      this.resetListHandle(this.searchHideList, "cloneSearchHideList");
      let reObj = cloneDeep(this.initParams);
      this.cloneParams = cloneDeep(reObj);
      this.initParamsHandle();
      this.$emit("input", this.cloneParams);
      if (this.isDeepSearch) return this.$emit("reset-back");
      this.$emit("search-back");
    },
    dateChangeHandle(val) {
      if (!val.value) {
        if (val.timePeriod) val.radio = "";
        this.cloneParams[val.startStr] = "";
        this.cloneParams[val.endStr] = "";
        return;
      }
      if (val.timePeriod) val.radio = "";
      if (val.nohmm || val.type == "datetimerange") {
        this.cloneParams[val.startStr] = val.value[0];
        this.cloneParams[val.endStr] = val.value[1];
      } else {
        this.cloneParams[val.startStr] = `${val.value[0]} 00:00:00`;
        this.cloneParams[val.endStr] = `${val.value[1]} 23:59:59`;
      }
    },
    deptChangeSelectHandle(val) {
      this.$nextTick(() => {
        this.cloneParams[val.id] = val.value.split(",")[0];
      });
    },
    inputBlurHandle(val) {
      this.cloneParams[val.id] = val.value;
    },
    selectChangeHandle(val) {
      this.cloneParams[val.id] = val.value;
    },
    locationChangeHandle(val) {
      const ids = val.id.split(",");
      if (ids.length == 1) {
        this.cloneParams[val.id] = val.value.join("/");
        return;
      }
      val.value.forEach((item, index) => {
        this.cloneParams[ids[index]] = item;
      });
    },
    changeCheckHandles(item, val, index) {
      let iArr = val.list;
      for (let i = 0; i < iArr.length; i++) {
        if (i == index) {
          iArr[i].checked = !iArr[i].checked;
        }
        if (index == 0 && iArr[i].checked) {
          iArr.forEach((item, index) => {
            item.checked = index == 0;
          });
          break;
        }
        if (index == 0 && !iArr[i].checked) {
          const fList = iArr.filter((item) => item.checked);
          if (fList.length < 1) {
            iArr[i].checked = true;
          }
          break;
        }
        if (index != 0 && iArr[i].checked) {
          const fList = iArr.filter((item) => item.checked);
          if (fList.length == iArr.length - 1) {
            iArr.forEach((item, index) => {
              item.checked = index == 0;
            });
          } else {
            iArr[0].checked = false;
          }
        }
      }
      if (iArr[0].checked) {
        this.cloneParams[val.id] = iArr[0].value;
      } else {
        const fList = iArr.filter((item) => item.checked);
        this.cloneParams[val.id] = [];
        fList.forEach((item) => {
          this.cloneParams[val.id] = this.cloneParams[val.id].concat(
            item.value
          );
        });
      }
    },
    openHandle() {
      this.isExpanded = !this.isExpanded;
    },
    enterSearch() {
      let inputList = this.$refs.input;
      inputList.forEach((item) => {
        item.blur();
      });
      this.searchHandle();
    },
    searchHandle() {
      this.cloneParams[this.currentWord] = 1;
      let emitParams = cloneDeep(this.cloneParams);
      this.$emit("input", emitParams);
      this.$emit("search-back");
    },
    clearValueHandle(val) {
      this.cloneParams[val.id] = "";
    },
    getLabelWidth() {
      let showLen = this.getMaxlabelHandle(this.searchShowList);
      let hideLen = this.getMaxlabelHandle(this.searchHideList);
      const maxLen = Math.max(showLen, hideLen);
      const isStar = this.searchShowList.some((obj) => obj.isNeed === true);
      this.widthLabel = maxLen * 14 + 16;
      if (isStar) this.widthLabel += 8;
    },
    getMaxlabelHandle(arr) {
      if (!arr.length) return 0;
      let list = arr.filter((item) => item.label !== undefined);
      if (!list.length) return 0;
      const maxTextLength = list.reduce((maxLength, obj) => {
        return Math.max(maxLength, obj.label.length);
      }, 0);
      return maxTextLength;
    },
  },
  mounted() {
    this.cloneParams = cloneDeep(this.value);
    this.initParams = cloneDeep(this.value);
    this.cloneSearchShowList = cloneDeep(this.searchShowList);
    this.cloneSearchHideList = cloneDeep(this.searchHideList);
    this.initParamsHandle();
    this.$nextTick(() => {
      this.getLabelWidth();
    });
  },
};
</script>

<style lang="scss" scoped>
.search-group {
  padding: 24px;
  border-radius: 8px;
  background-color: #ffffff;
  display: flex;
  .group-left {
    flex: 1;
    width: 0;
    transition: all 0.3s;
    .group-list-wrap {
      display: flex;
      flex-wrap: nowrap;
      .group-item-wrap {
        height: 32px;
        display: flex;
        align-items: center;
        padding-right: 24px;

        .search-label {
          text-align: right;
          color: rgba($color: #000000, $alpha: 0.9);
          font-weight: 400;
          font-size: 14px;
          padding-right: 16px;
          span {
            font-size: 14px;
            color: rgba(#000, 0.9);
            font-weight: 400;
            font-size: 14px;
          }
          .star {
            display: none;
            // display: inline-block;
            text-align: center;
            width: 8px;
            color: #e34d59;
            font-size: 12px;
          }
        }

        .search-item-right {
          width: 0;
          flex: 1;
          display: flex;
          align-items: center;
        }
        &.is-need {
          .search-label {
            .star {
              display: inline-block !important;
            }
          }
        }
      }

      .check-box {
        flex: 1;
        display: flex;
        align-items: center;

        .check-item {
          display: flex;
          align-items: center;
          margin-right: 24px;

          &:last-child {
            margin-right: 0;
          }
        }

        .check-icon {
          height: 16px;
          width: 16px;
          margin-right: 8px;
          border-radius: 3px;
          border: 1px solid #dcdcdc;
          cursor: pointer;
        }

        .check-icon.active {
          border: 1px solid #0087d6;
          background: #0087d6;
          background-image: url("~@/assets/icons/check_active_icon.png");
          background-size: contain;
        }
        .check-label {
          color: rgba(#000, 0.9);
          font-weight: 400;
          font-size: 14px;
          white-space: nowrap;
        }
      }
    }
    .search-hidden-wrap {
      padding-top: 24px;
      .group-list-wrap {
        flex-wrap: wrap;
      }
      .group-item-wrap {
        margin-bottom: 24px;
      }
    }
  }
  .group-right {
    background: #ffffff;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: flex-end;

    .open-btn {
      position: relative;
      color: #0087d6;
      font-weight: 400;
      font-size: 14px;
      cursor: pointer;
      background-color: #ffffff;
      &::after {
        content: "";
        width: 0px;
        height: 0px;
        border-top: 6px solid #0087d6;
        border-left: 6px solid transparent;
        border-right: 6px solid transparent;
        position: absolute;
        top: 6px;
        right: -21px;
        transition: 0.3s;
      }
    }

    .open-btn.active {
      &::after {
        transform: rotate(180deg);
      }
    }

    .search-btn {
      height: 32px;
      padding: 0 15px;
      line-height: 32px;
      text-align: center;
      font-weight: 400;
      font-size: 14px;
      border-radius: 3px;
      border: 1px solid #0087d6;
      cursor: pointer;
      color: #ffffff;
      background-color: #0087d6;
      transition: all 0.3s;
      &.search {
        margin: 0 16px 0 36px;
        &:hover {
          background: #4e52da;
          border: 1px solid #4e52da;
        }
      }
      &.reset {
        background-color: #ffffff;
        color: #0087d6;
        &:hover {
          color: #4e52da;
          border: 1px solid #4e52da;
        }
      }
    }
    &.unneed {
      .search-btn.search {
        margin: 0 16px 0 0;
      }
    }
  }
}
</style>
